#-*-coding:utf-8-*-
'''
李雅普诺夫计算,按定义算
'''
from math import *

class lyapuruo1:
    '''
    Use the definition to generate the index
    '''
    def __init__(self):
        '''
        apply some varieties to save the content
        '''
        self.xArray = list() #to save the original array
        self.derivativeArray = list() #to save the derivative array
        self.Arraylenth = 0 #to save the length of the array

    def CreateArrays(self,x0,lenth):
        '''
        Generate the original array and the derivative array
        '''
        self.__init__()         #clear the varieties
        i = 0 #the step of the loop to generate the arrays
        self.xArray.append(x0)
        self.Arraylenth = lenth     #to save the first element of the array and the length of the array.

        while i < lenth:
            #self.xArray.append((1.0 / (1.0 - self.xArray[i])) - (1.0 / (1.0 + self.xArray[i])))
            #self.xArray.append(4.0 * self.xArray[i] - 4.0 * self.xArray[i] * self.xArray[i])
            self.xArray.append(2.0 * self.xArray[i] / (1 - self.xArray[i] ** 2))
            #print self.xArray[i]
            #self.derivativeArray.append(abs((1.0 / pow(1.0 - self.xArray[i],2)) + (1.0 / pow(1.0 + self.xArray[i],2))))
            #self.derivativeArray.append(abs(4 - 8 * self.xArray[i]))
            self.derivativeArray.append(abs( 2 + 2 * (self.xArray[i] ** 2)) / (1 - (self.xArray[i] ** 2)) ** 2)
            i += 1

    def GetIndex(self,n):
        '''
        Get the index
        '''
        re = 0
        #print self.derivativeArray
        for i in self.derivativeArray:
            re += log(i)
        return re/n


class Maxlyapuruo:
    '''
    the second method to calc the index.
    '''
    def __init__(self):
        self.xArray = list()  #to save the original x array
        self.yArray = list()  #to save the original y array
        self.di = list() #to save the di
        self.length = 0 #the length of the arrays

    def CreateArrays(self,xa0,ya0,d0,length,tao):
        '''
        To generate x array and y array!
        xa0 refer to the initial value of the expression [x,y]
        ya0 refer [x,y]
        d0 refer to the degree of the adjustment
        length refer to the length of the arrays
        '''
        self.__init__()     #clear the varieties' memory
        self.xArray.append(xa0)
        self.yArray.append(ya0)
        self.length = length
        self.tao = tao
        #self.di.append(d0)
        i = 0 #the step of the loop
        self.logd = 0 #record the log(di/d0)
        while i < length:
            self.di.append(sqrt(pow(self.yArray[i][0] - self.xArray[i][0],2) + pow(self.yArray[i][1].imag - self.xArray[i][1].imag,2)))
            #print self.di
            #print self.xArray
            #print self.yArray
            self.logd += log(abs(self.di[i] / self.di[0]))      #calc di and the di/d0
            #self.xArray.append([self.xArray[i][0],(2.0 * self.xArray[i][0]) / (1.0 - self.xArray[i][0] * self.xArray[i][0])])
            self.xArray.append([
                                (2.0 * self.xArray[i][0]) / (1.0 - self.xArray[i][0] * self.xArray[i][0]),
                                ((self.xArray[i][1] * self.xArray[i][1] + 1.0) / 2.0 * self.xArray[i][1]
                                )])
            yb1x = 2.0 * self.yArray[i][0] / (1.0 - self.yArray[i][0] * self.yArray[i][0])
            yb1y = (self.yArray[i][1] * self.yArray[i][1] + 1) / (2 * self.yArray[i][1])
            xb0 = self.xArray[i + 1][0] + self.di[0] * (yb1x - self.xArray[i + 1][0])
            yb0 = self.xArray[i + 1][1].imag + self.di[0] * (yb1y.imag - self.xArray[i + 1][1].imag)
            self.yArray.append([xb0,complex(0,yb0)])
            i += 1
        #print self.xArray

    #def GetTao(self):
    #    '''
    #    calc the Tao.Get the average value of the samples such as d1/d0
    #    '''
    #    #klen = len(self.di)
    #    re = 0
    #    for i in range(self.length):
    #        re += (float)(log(abs(self.di[i+1] / self.di[i])) / log(2))     #loop to get the di list
    #    return re/self.length

    def GetIndex(self,tao = 1):
        '''
        Get the result/index.
        '''
        #tao = self.GetTao()
        #tao = 1
        #klen = len(self.di)
        #print klen
        #re = 0
        #for i in range(self.length):
            #re += float(log(abs(self.di[i + 1] / self.di[0])))
        #return  re / (self.length * tao)
        if not self.xArray:
            return False
        else:
            return self.logd / (self.length * self.tao)

    def test(self):
        '''
        for test!
        '''
        xa0 = [3.0,complex(0,0.6)]
        ya0 = [3.000001,complex(0,0.6)]
        d0 = 0.000001
        length = 10000
        tao = 1
        self.CreateArrays(xa0,ya0,d0,length,tao)
        print self.GetIndex()


